home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swags_z.zip / SCROLL.SWG / 0018_Smooth Text-VGA Scrolling.pas < prev    next >
Pascal/Delphi Source File  |  1995-03-03  |  8KB  |  274 lines

  1. {
  2. >I want to write a routine to scroll text smoothly i.e. pixel wise. This
  3. >might be ambitious as I know almost nothing about pogramming the display
  4. >card, but I have two theories. The one will work, but is very long
  5. >winded. Please advise me on a course of action.
  6.  
  7. >BTW, can anyone recommend any good books on topics such as the above,
  8. >i.e. advanced graphics programming etc. When giving advice please
  9. >remember my coding ability is way behind the ability to figure
  10. >algorithms.
  11.  
  12.  
  13. One of the best books I've read is PC and PS/2 video systems by
  14. microsoft press (if I/'m correct). It deals with a lot of great topics
  15. like graphs in textmode and the differences between video cards.
  16.  
  17. The best way to start it is to re-program the starting line of the
  18. display. This way you've got hardware scrolling in textmode. Only
  19. program is when & were to insert a new line.
  20.  
  21. I know that PC-magazine once published a smooth scrolling routine in
  22. textmode. This one should contain all info you need.
  23.  
  24. Btw here's a small demo of how to re-program the starting line of a
  25. E/VGA card. Once re-programmed you see the second text page of the E/VGA
  26. card.
  27.  
  28.  
  29. {---------------------------------------------------------}
  30. {  Project : Split screen for EGA & VGA                   }
  31. {  Auteur  : Wim van der Vegt                             }
  32. {---------------------------------------------------------}
  33. {  Datum .tijd  Revisie                                   }
  34. {  910505.1645  Creatie.                                  }
  35. {---------------------------------------------------------}
  36.  
  37. Program split(INPUT,OUPUT);
  38.  
  39. {----Source of information :
  40.  
  41.      Programmer's Guide to PC & PS/2 Video Systems, by Microsoft press
  42.  
  43. }
  44.  
  45. uses
  46.   crt,
  47.   dos,
  48.   graph;
  49.  
  50. VAR
  51.   vgacard  : BOOLEAN;
  52.   gvmax,
  53.   tvmax    : INTEGER;
  54.   r        : Registers;
  55.   grmode,
  56.   grdriver : INTEGER;
  57.  
  58. {---------------------------------------------------------}
  59.  
  60. var
  61.   v,i,j    : integer;
  62.  
  63. const
  64.   CRTC_adr = $3D4;
  65.   CRTC_dat = $3D5;
  66.  
  67. {---------------------------------------------------------}
  68. {----Wait for vertical retrace                            }
  69. {---------------------------------------------------------}
  70.  
  71. procedure V_retrace; inline($BA/$DA/$03/ { mov dx,$03DA   }
  72.                             $EC/         { in al,dx   <-\ }
  73.                             $A8/$08/     { test al,8    | }
  74.                             $75/$FB/     { jnz >--------/ }
  75.                             $EC/         { in al,dx   <-\ }
  76.                             $A8/$08/     { test al,8    | }
  77.                             $74/$FB);    { jz >---------/ }
  78.  
  79. {---------------------------------------------------------}
  80. {----Sets re-start line for CRTC controller               }
  81. {---------------------------------------------------------}
  82.  
  83. procedure CRTC_split(i : WORD);
  84.  
  85. VAR
  86.   b : BYTE;
  87.  
  88. begin
  89.   V_retrace;
  90.   IF vgacard
  91.     THEN
  92.       BEGIN
  93.         port[CRTC_adr]:=$09; b:=port[CRTC_dat];
  94.         port[CRTC_adr]:=$09; port[CRTC_dat]:=BYTE(b AND $BF)+(BYTE(i DIV 512)) ;
  95.         port[CRTC_adr]:=$18; port[CRTC_dat]:=BYTE(i MOD 256);
  96.         port[CRTC_adr]:=$07; b:=port[CRTC_dat];
  97.         port[CRTC_adr]:=$07; port[CRTC_dat]:=BYTE(b AND $ef)+BYTE((i DIV 256)) ;
  98.       END
  99.     ELSE
  100.       BEGIN
  101.         port[CRTC_adr]:=$18; port[CRTC_dat]:=i MOD 256;
  102.         port[CRTC_adr]:=$07; port[CRTC_dat]:=$ef+((BYTE(i DIV 256) MOD 2) SHL 4)
  103.        END;
  104. end; {of CRTC_split}
  105.  
  106. {---------------------------------------------------------}
  107. {----Sets display start address for CRTC controller       }
  108. {---------------------------------------------------------}
  109.  
  110. procedure CRTC_start(i : word);
  111.  
  112. begin
  113.   port[CRTC_adr]:=$0d; port[CRTC_dat]:=i mod 256;
  114.   port[CRTC_adr]:=$0c; port[CRTC_dat]:=i div 256;
  115. end; {of CRTC_start}
  116.  
  117. {---------------------------------------------------------}
  118. {----Resets the screen split                              }
  119. {---------------------------------------------------------}
  120.  
  121. PROCEDURE Unsplit;
  122.  
  123. BEGIN
  124.   CRTC_start(0);
  125.   CRTC_split($1ff);
  126. END;
  127.  
  128. {---------------------------------------------------------}
  129. {----Graphic mode, mouse controlled screen split          }
  130. {---------------------------------------------------------}
  131.  
  132. Procedure do_graph_split;
  133.  
  134. begin
  135. {----get motion count from mouse}
  136.   r.ax:=$000B;
  137.   INTR($33,r);
  138.   v:=v+INTEGER(r.dx);
  139.  
  140.   if v>gvmax THEN v:=gvmax;
  141.   if v<0     THEN v:=0;
  142.   IF v>0
  143.     THEN
  144.     {----By adjusting this value according to v,
  145.          the two EGA/VGA graphic screens will be linked}
  146.       begin
  147.       {----Second Graph Screen 32K after start of First Screen}
  148.         CRTC_start($8000);
  149.         CRTC_split(v);
  150.       end
  151.     ELSE Unsplit;
  152. end;
  153.  
  154. {---------------------------------------------------------}
  155. {----Text mode, mouse controlled screen split             }
  156. {---------------------------------------------------------}
  157.  
  158. Procedure do_text_split;
  159.  
  160. begin
  161. {----get motion count from mouse}
  162.   r.ax:=$000B;
  163.   INTR($33,r);
  164.   v:=v+INTEGER(r.dx);
  165.  
  166.   if v>tvmax THEN v:=tvmax;
  167.   if v<0     THEN v:=0;
  168.   IF v>0
  169.     THEN
  170.       begin
  171.       {----Second text Screen 4K after start of First Screen}
  172.         CRTC_start($1000);
  173.         CRTC_split(v);
  174.       end
  175.     ELSE Unsplit;
  176. end;
  177.  
  178. {=========================================================}
  179.  
  180. BEGIN
  181. {----Screen must be EGA or VGA}
  182.   grdriver:=detect;
  183.   Detectgraph(grdriver,grmode);
  184.   vgacard:=(grdriver=vga);
  185.  
  186. {----Graphics Mode, watch out,
  187.      VGA hasn'got two pages in 640x480 graphics mode,
  188.      switch to EGA 640x350 mode if you want two full pages,
  189.      and change gvmax below from 479 to 349}
  190.  
  191.   IF vgacard
  192.     THEN gvmax:=479
  193.     ELSE gvmax:=349;
  194.  
  195. {----Text Mode, VGA in text mode has 400 lines (So NOT 480 lines !!) }
  196.   IF vgacard
  197.     THEN tvmax:=399
  198.     ELSE tvmax:=349;
  199.  
  200.   IF (grdriver<>vga) AND (grdriver<>ega)
  201.     THEN
  202.       BEGIN
  203.         Writeln('Ega or Vga Card NOT Found');
  204.         Halt;
  205.       END;
  206.  
  207. {----Text mode demo #1}
  208.   FOR i:=0 TO 80*25 DO
  209.     BEGIN
  210.       MEMW[$B800:i*2]:=$0F30;
  211.       MEMW[$B900:i*2]:=$3031;
  212.     END;
  213.  
  214. {----Oscillating Screen Split}
  215.   CRTC_start($1000);
  216.   for i:=8 to 192 do CRTC_split( round(175-175*cos(i/30*pi)*(8/i)) );
  217.   Delay(1000);
  218.  
  219. {----Accelerating screen split}
  220.   for i:=3*175 downto 16 do CRTC_split( Trunc(175-(175/i)*16) );
  221.   Delay(1000);
  222.   Unsplit;
  223.  
  224. {----Text mode demo #2 & Graphics demo #1 need a mouse}
  225.   r.ax:=$0000;
  226.   INTR($33,r);
  227.   IF (r.ax=0)
  228.     THEN
  229.       BEGIN
  230.         Writeln('Microsoft mouse NOT Found');
  231.         Halt;
  232.       END;
  233.  
  234. {----Text mode demo #2}
  235.   GotoXY(10,09);
  236.   Write('                                                           ');
  237.   GotoXY(10,10);
  238.   Write('  Now Move your mouse up and down and see text page 0 & 1  ');
  239.   GotoXY(10,11);
  240.   Write('            Press SPACE key to exit this demo              ');
  241.   GotoXY(10,12);
  242.   Write('                                                           ');
  243.  
  244.   v:=50;
  245.   WHILE NOT(keypressed AND (Readkey=#32)) DO Do_text_split;
  246.   Unsplit;
  247.  
  248. {----Graphic Mode Demo #1, works best on EGA and VGA in EGA mode}
  249.   grdriver:=ega;
  250.   grmode:=egahi;
  251.   Initgraph(grdriver,grmode,'e:\bp\bgi');
  252.   Setcolor(blue);
  253.   FOR i:=0 TO gvmax DO
  254.     FOR j:=0 TO 39 DO
  255.       memw[$a000:WORD(i*80)+2*j]:=$1000;
  256.   Setcolor(red);
  257.   FOR i:=0 TO gvmax DO
  258.     FOR j:=0 TO 39 DO
  259.       memw[$a800:WORD(i*80)+2*j]:=$0010;
  260.   Setcolor(white);
  261.   Outtextxy(10,10,'  This is Graphic page 0, Move your mouse & press space to e');
  262.   Rectangle(0,0,639,gvmax);
  263.   Setactivepage(1);
  264.   Outtextxy(10,10,'  This is Graphic page 1  ');
  265.   Rectangle(0,0,639,gvmax);
  266.  
  267.   v:=50;
  268.  
  269.   WHILE NOT(keypressed AND (Readkey=#32)) DO Do_graph_split;
  270.   Unsplit;
  271.  
  272.   Closegraph;
  273. END.
  274.